﻿/*
 * Created by SharpDevelop.
 * User: Hellen(LongFan)
 * Date: 2015/12/24
 * Time: 20:27
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */
using System;
using System.Windows.Forms;
using System.IO.Ports;
using System.Collections.Concurrent;

namespace Comm
{
	/// <summary>
	/// Description of Class1.
	/// </summary>
	//my serialport class	
	public class MyCommClass
	{
		//My Serial Port Class
		public static string SPortName = null;   
		public static int SBaudRate;   
		public static byte SByteSize;   
		public static byte SParity = 0; // 0-4=no,odd,even,mark,space   
		public static byte SStopBits = 0; // 0,1,2 = 1, 1.5, 2   
		public static int ReadTimeout; 
  
		public static bool Opened = false; 		//Port is opened
		public static bool Working = false;		//the port is working, do not close
		public static int ReceivedCount = 0;	//Received count
		
		private volatile bool EnableReceive = true;	//enable do event handle ro not
		private byte[] buf = new byte[1];		//receive buffer
        private int NoToRead = 0;				//nomber byte to read
		
		public SerialPort MySerialPort = new SerialPort();

        public void Open()
        {//if this comm is opened, close it first
        	if(MySerialPort.IsOpen)
        	{
        		MySerialPort.Close();
        		Opened = false;
        	}
        	//set comm configuration
        	MySerialPort.BaudRate = SBaudRate;
        	MySerialPort.PortName = SPortName;
        	MySerialPort.DataBits = SByteSize;
        	switch(SStopBits)
        	{
        		case 0:
        			MySerialPort.StopBits = StopBits.One;
        			break;
        		case 1:
        			MySerialPort.StopBits = StopBits.OnePointFive;
        			break;
        		case 2:
        			MySerialPort.StopBits = StopBits.Two;
        			break;
        		default:
        			MySerialPort.StopBits = StopBits.One;
        			break;
        	}
        	switch(SParity)
        	{
        		case 0:
        			MySerialPort.Parity = Parity.None;
        			break;
        		case 1:
        			MySerialPort.Parity = Parity.Odd;
        			break;
        		case 2:
        			MySerialPort.Parity = Parity.Even;
        			break;
        		default:
        			MySerialPort.Parity = Parity.None;
        			break;
        	}
        	MySerialPort.ReadBufferSize = 1024000;
        	MySerialPort.NewLine = "/r/n";
        	MySerialPort.ReceivedBytesThreshold = 1;
        	try
        	{
        		MySerialPort.Open();
        	}
        	catch(Exception ex)
        	{
        		MessageBox.Show(ex.Message);
        	}
        	//Check open comm successed or not
        	if(MySerialPort.IsOpen)
        	{
        		Opened = true;
        		EnableReceive = true;
        	}
        }
        
        public bool Close()
        {
        	EnableReceive = false;		//stop receive event
        	
        	while(Working)	;		//wait it is not working(read all readbuffer)
//        		Application.DoEvents();
        	
	        if(MySerialPort.IsOpen)
	        {
				MySerialPort.DiscardInBuffer();	//clear read buffer
	        	MySerialPort.Close();
	        	Opened = false;			//set flag
	        	return true ;
	        }
	        else
	        {
	        	MessageBox.Show("No Serial Port Is Opened!");
	        	return false;
	        }
        }
        //serialPort cotrol DataReceived Event handle function
        public void MySerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
        	if(EnableReceive)
        	{
// 				FileStream MyCSVFS = new FileStream(@".\Data\MyTest.csv",FileMode.Create,FileAccess.Write);
//	 			StreamWriter MyCSVWS = new StreamWriter(MyCSVFS, System.Text.Encoding.UTF8);
				DealDataThread.DataDealing = true;			//received data, start the deal data function in deal thread
	        	try
	        	{
	        		Working = true;
	        		//MySerialPort.ReceivedBytesThreshold = 1000;
	        		NoToRead = MySerialPort.BytesToRead;
	        		ReceivedCount += NoToRead ;
	        		while( 0 < NoToRead )
	        		{
	        			//If received data, palce the data to Queue
	        			MySerialPort.Read(buf,0,1);
	//        			Array.Reverse(buf);
	//        			MyCSVWS.WriteLine(Convert.ToString(BitConverter.ToUInt16(buf,0))+",");
						MainForm.MyReDataQueue.Enqueue(buf[0]);		//fill the data queue
						if(UpdataCurveThreadClass.DataToCurveQueueEn)
						{//if enable Updata Curve, fill data to curve queue
							UpdataCurveThreadClass.CurveDataQueue.Enqueue(buf[0]);		//fill the curve queue
						}
						NoToRead--;
	        		}
	
	        	}
	        	finally
	        	{
	        		//MySerialPort.ReceivedBytesThreshold = 1;
	        		Working = false;
	        	}
        	}//if not enable receive,read the 
        }
        
//        public byte[] Read(int NumBytes)
//        {
//            byte[] BufBytes;
//            byte[] OutBytes;
//            BufBytes = new byte[NumBytes];
//            if (Opened)
//            {
//                int BytesRead = 0;
//                MySerialPort.Read(BufBytes,0,NumBytes);
//                OutBytes = new byte[BytesRead];
//                Array.Copy(BufBytes, OutBytes, BytesRead);
//            }
//            else
//            {
//                throw (new ApplicationException("Comm Port Not Open"));
//            }
//            return OutBytes;
//        }
        
        public int Write(byte[] WriteBytes)
        {
            int BytesWritten = 0;
            if (Opened)
            {
            	MySerialPort.Write(WriteBytes,0,WriteBytes.Length);
            }
            else
            {
                throw (new ApplicationException("Comm Port Not Open"));
            }
            return BytesWritten;
        }        
	}
}
